#!/usr/bin/env python
# -*- coding:utf-8 -*-

import json #用户raw_input输入的是字符串，用loads()方法将字符串恢复用户的输入格式；
import os   #用于重命名文件名，windows下会报错，linux使用正常；

'''
获取查看的思路：
1、读取每行数据，用strip去掉空格和换行，匹配用户的输入；
2、设定一个标志位，当匹配到用户的backend那行的时候，设标志位为真；
3、如果下面的record行标志位为1，并且不为空，就放入一个列表；
4、再往下，看到以backend开头的行，此时标志位还是真，就结束循环；
5、为什么4在3的前面判断？因为不知道有几条记录，读到下一个backend时候还是会插入列表。
so：设定开始的位置-->设定结束的位置-->获取中间值
'''
def fetch(domain): #定义查看函数，将用户输入的域名为参数传入函数；
    with open('config','r')as fr:
        fetch_list=[]
        flag=0
        for line in fr:
            if line.strip()=="backend %s" % domain:
                flag=1
                continue    #如果不用continue，下面的条件也满足，就无意义了；
            if flag and line.strip().startswith("backend"):
                break
            if flag and line.strip():
                fetch_list.append(line.strip())
    return fetch_list

'''
增加配置的思路：
1、先获取要增加的backend下所有记录列表，直接调取fetch()函数获得；
2、如果先前没有这个backend段落，那直接把他们都加进去就行了；
3、如果有backend段落，分两种情况判断，一种是这个值已经存在了，退出；另一种是不存在，直接插入；
4、匹配数据的时候，尽量把字符串弄得简洁，利用格式化的方式匹配；
5、此段backend通过一个列表（获取的列表和新加入值组成的新列表）单独插入文件，其它行直接写入新文件；
6、按照fetch()的逻辑，通过标志位，设定开始点和结束点，中间这一段是写入列表中的数值；
7、注意点：如果原有列表的backend有多个record，当读到第二个的时候，就又把列表插入了一回，所以要设定一个标志位has_write，写完了一遍后就置为1，下面的行一看已经写过了，就不再写了；
so:设定开始的位置-->设定结束的位置-->写入文件-->设定已写入标志-->其它行原行搬入
'''
def add_record(dic_user):
    #直接判断这个域名下有没有返回值，如果有，就插入，没有就全部写入；
    domain=dic_user["backend"]
    current_backend="backend %s" % domain
    current_record="server %s weight %s maxconn %s" % (dic_user["record"]["server"],dic_user["record"]["weight"],dic_user["record"]["maxconn"])
    fetch_list=fetch(domain)
    if fetch_list:
        if current_record in fetch_list:           #还得判断这个记录有没有
            print "已有此record"
        else:
            fetch_list.append(current_record)       #把用户输入的record加入列表，以备一会写入文件；
            with open('config','r')as fr,open('config.new','w')as fw:   #python2.7以上可以同时打开两个描述符
                flag=0      #起始标志位
                has_write=0 #没有这句的话，读到backend其它行时，flag还是True，又会循环一遍列表插入。
                for line in fr:
                    if line.strip() == current_backend:
                        fw.write(line)
                        flag=1
                        continue
                    elif flag and line.strip().startswith("backend"):
                        fw.write(line)
                        flag=0
                    elif flag and line.strip() :
                        if not has_write:
                            for new_line in fetch_list:
                                fw.write("%s%s\n" % (" "*8,new_line))
                            has_write=1
                    else:       #非backend段落直接写入
                        fw.write(line)
            print "添加record成功"
    else:#全部写入
        with open('config','r')as fr,open('config.new','w')as fw:
            for line in fr:
                fw.write(line)
            fw.write("backend %s\n" % domain)
            fw.write("%s%s\n" % (" "*8,current_record))
        print "添加backend和record成功"
    #os.renames('config','config.bak')   #把所有改动写到一个新文件，原文件改名备份，新文件改成原文件的名字；
    #os.renames('config.new','config')

'''
删除配置的思路：
1、总体思路和add差不多，只是把append换成remove
2、同样需要用到起始标志位和写入标志位
3、就是把有的写入新文件，没有的去掉就不写入了；
'''
def del_record(dic_user):
    domain=dic_user["backend"]
    current_backend="backend %s" % domain
    current_record="server %s weight %s maxconn %s" % (dic_user["record"]["server"],dic_user["record"]["weight"],dic_user["record"]["maxconn"])
    del_list=fetch(domain)
    if del_list:
        if current_record in del_list:
            del_list.remove(current_record)
            with open('config','r')as fr,open('config.new','w')as fw:
                flag=0
                has_write=0
                for line in fr:
                    if line.strip()==current_backend:
                        flag=1
                        if del_list:    #如果还有record的话，还要把这行加上；
                            fw.write(line)
                    elif flag and line.strip().startswith("backend"):
                        fw.write(line)  #这行要写入
                        flag=0
                    elif flag :
                        if not has_write:
                            for new_line in del_list:
                                fw.write("%s%s\n" % (" "*8,new_line))
                            has_write=1
                    else:
                        fw.write(line)
            print "deleted"
        else:print "此域名下没有这个分发记录"
    else:print "没有此域名的分发"
    #os.renames('config','config.bak')
    #os.renames('config.new','config')

while True:
    operation=["获取ha记录","增加ha记录","删除ha记录","退出"]
    for num,operate in enumerate(operation,1):
        print num,operate

    user_select=raw_input("please select number:")
    if user_select == '1':
        user_fetch=raw_input("请输入域名查看：")
        if fetch(user_fetch):
            for record in fetch(user_fetch):
                print record
        else:
            print "no match"
    if user_select=='2':
        user_add=raw_input("请输入增加的记录：")
        user_add=json.loads(user_add)
        add_record(user_add)
    if user_select=='3':
        user_del=raw_input("请输入删除的记录：")
        user_del=json.loads(user_del)
        del_record(user_del)
    if user_select=='4':
        break